(function () {
    'use strict';
    var describe = BDD.describe, it = BDD.it, expect = BDD.expect;

    describe('Matrix', function () {
        describe('creation', function () {
            it('creates zero matrices', function () {
                expect(Matrix.zeros(2)).to.equal(new Matrix([[0, 0], [0, 0]]));
                expect(Matrix.zeros(3)).to.equal(new Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]]));

                expect(Matrix.zeros(2, 3)).to.equal(new Matrix([[0, 0, 0], [0, 0, 0]]));
            });

            it('creates identity matrices', function () {
                expect(Matrix.eye(2)).to.equal(new Matrix([[1, 0], [0, 1]]));
                expect(Matrix.eye(3)).to.equal(new Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]));
            });

            it('assumes zeros when argument not rectangular', function () {
                expect(new Matrix([[1], [0, 1]])).to.equal(Matrix.eye(2));
                expect(new Matrix([[1], [0, 1], [0, 0, 1]])).to.equal(Matrix.eye(3));
            });
        });

        describe('multiplication', function () {
            it('Matrix * Array', function () {
                expect(Matrix.eye(2).times([3, 4])).to.equal([3, 4]);
                expect(new Matrix([[1, 2], [3, 4], [5, 6]]).times([3, 4])).to.equal([11, 25, 39]);
            });

            it('Matrix * Matrix', function () {
                expect(Matrix.eye(2).times(Matrix.eye(2))).to.equal(Matrix.eye(2));
                expect(new Matrix([[1, 2], [3, 4]]).times(new Matrix([[1, 2], [3, 4]]))).to.equal(new Matrix([[7, 10], [15, 22]]));
            });

            describe('with mismatched dimensions', function () {
                var m, msg;

                m = Matrix.eye(2);
                msg = /dimensions mismatch/;

                it('throws in Matrix * Array', function () {
                    expect(m.times).with(m, [1]).to.throw(msg);
                });

                it('throws in Matrix * Matrix', function () {
                    expect(m.times).with(m, Matrix.eye(3)).to.throw(msg);
                });
            });
        });
    });
}());
